using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ListItemEditor
{
    public partial class SelectForm : Form
    {
        private bool _inHandler;
        private bool _afterOnLoad;

        public SelectForm()
        {
            InitializeComponent();
        }

        public List<string> SelectedItems
        {
            get 
            {
                return this.lvItems.Items.Cast<ListViewItem>().Where(it => it.Checked).Select(it => it.Text).ToList();
            }
            set
            {
                HashSet<string> set = new HashSet<string>(value);
                foreach (ListViewItem item in this.lvItems.Items.Cast<ListViewItem>().Where(it => set.Contains(it.Text))) item.Checked = true;
            }
        }

        public List<string> Items
        {
            get
            {
                return this.lvItems.Items.Cast<ListViewItem>().Select(it => it.Text).ToList();
            }
            set 
            {
                this.lvItems.Items.Clear();
                this.lvItems.Items.AddRange(
                    value.Select(s => new ListViewItem(s)).ToArray()
                    );
            }
        }

        public bool MultipleSelect { get; set; }

        private void cbAll_CheckedChanged(object sender, EventArgs e)
        {
            bool check = this.cbAll.Checked;
            foreach (ListViewItem item in this.lvItems.Items)
            {
                item.Checked = check;
            }
        }

        private void SelectForm_Load(object sender, EventArgs e)
        {
            _afterOnLoad = true;
            if (!this.MultipleSelect) this.cbAll.Visible = false;
        }

        private void lvItems_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            if (this.MultipleSelect || _inHandler || !_afterOnLoad) return;
            try
            {
                _inHandler = true;
                bool check = e.Item.Checked;
                if (!check) { e.Item.Checked = true; return; }
                foreach (ListViewItem item in this.lvItems.Items)
                {
                    item.Checked = false;
                }
                e.Item.Checked = true;
            }
            finally
            {
                _inHandler = false;
            }
        }

        public static DialogResult ShowSelect(IWin32Window parent, string caption, List<string> items, ref List<string> selectedItems, bool multiple)
        {
            if (items == null) items = new List<string>();
            if (selectedItems == null) selectedItems = new List<string>();

            SelectForm form = new SelectForm();

            form.Text = caption;
            form.MultipleSelect = multiple;
            form.Items = items;
            form.SelectedItems = selectedItems;

            DialogResult result = form.ShowDialog(parent);
            if (result == DialogResult.OK) selectedItems = form.SelectedItems;
            return result;
        }
    }
}